#include "triangle.h"
#include <QSGVertexColorMaterial>
#include <QSGGeometry>
#include <QSGGeometryNode>
#include <QSGMaterial>
#include <QSGTransformNode>

Triangle::Triangle(QQuickItem* parent)
    : Super(parent)
{
    setFlag(Super::ItemHasContents);
}

Triangle::~Triangle() { }
static QColor fColor(qreal r, qreal g, qreal b, qreal a = 1.0)
{
    return QColor((int)(r * 255), (int)(g * 255), (int)(b * 255), (int)(a * 255));
}
QSGNode* Triangle::updatePaintNode(QSGNode* oldNode, UpdatePaintNodeData* data)
{
    (void)data;

    QSGGeometry*     geo = nullptr;
    QSGGeometryNode* node = nullptr;
    QSGTransformNode *transNode = nullptr;
    const int        cVertexCount = 3;
    if (!oldNode)
    {
        node = new QSGGeometryNode;
        geo = new QSGGeometry(QSGGeometry::defaultAttributes_ColoredPoint2D(), cVertexCount);
        geo->setLineWidth(1);
        geo->setDrawingMode(QSGGeometry::DrawTriangles);

        node->setGeometry(geo);
        node->setFlag(QSGNode::OwnsGeometry);

        auto material = new QSGVertexColorMaterial;

        node->setMaterial(material);
        node->setFlag(QSGNode::OwnsMaterial);

        transNode = new QSGTransformNode;

        transNode->appendChildNode(node);
    }
    else
    {
        transNode = static_cast<QSGTransformNode *>(oldNode);
        node = static_cast<QSGGeometryNode*>(transNode->childAtIndex(0));
        geo = node->geometry();
        geo->allocate(cVertexCount);
    }
    auto vertices = geo->vertexDataAsColoredPoint2D();
    int  w = width();
    int  h = height();
    QColor c1 = fColor(1.0, 0.0, 0.0);
    QColor c2 = fColor(0.0, 1.0, 0.0);
    QColor c3 = fColor(0.0, 0.0, 1.0);
    vertices[0].set(0.5 * w, 0.1 * h, c1.red(), c1.green(), c1.blue(), c1.alpha());
    vertices[1].set(0.9 * w, 0.9 * h, c2.red(), c2.green(), c2.blue(), c2.alpha());
    vertices[2].set(0.1 * w, 0.9 * h, c3.red(), c3.green(), c3.blue(), c3.alpha());
    node->markDirty(QSGNode::DirtyGeometry);

    QMatrix4x4 mat;
    mat.translate(width() /2, height() /2);
    mat.rotate(angle(), 0, 0, 1);
    mat.translate(-width() /2, -height() /2);
    transNode->setMatrix(mat);

    return transNode;
}

int Triangle::angle() const
{
    return mAngle;
}

void Triangle::setAngle(int newAngle)
{
    if (mAngle == newAngle)
        return;
    mAngle = newAngle;
    emit angleChanged();
    update();
}
